using Shared.Domain.Shared.Enums.UserService;
using Shared.Tools.Helper;
using SqlSugar;
using Volo.Abp.Auditing;
using Volo.Abp.Domain.Entities;
using Yookeii.Blog.Domain.Chat;

namespace UserService.Domain.Entities;

/// <summary>
/// 用户实体
/// </summary>
/// <summary>
/// 用户实体
/// </summary>
[SugarTable("Users")]
public sealed class UserAggregateRoot : AggregateRoot<Guid>, ISoftDelete, IHasCreationTime
{
    /// <summary>
    /// 用户唯一标识
    /// </summary>
    [SugarColumn(IsPrimaryKey = true, IsIdentity = false)]
    public override Guid Id { get; protected set; }
    /// <summary>
    /// 用户名
    /// </summary>
    [SugarColumn(Length = 50, IsNullable = false)]
    public string UserName { get; private set; }

    /// <summary>
    /// 昵称
    /// </summary>
    [SugarColumn(Length = 50, IsNullable = true)]
    public string NickName { get; private set; }

    /// <summary>
    /// 邮箱
    /// </summary>
    [SugarColumn(Length = 100, IsNullable = true)]
    public string Email { get; private set; }

    /// <summary>
    /// 手机号码
    /// </summary>
    [SugarColumn(Length = 20, IsNullable = true)]
    public string PhoneNumber { get; private set; }

    /// <summary>
    /// 密码值对象
    /// </summary>
    [SugarColumn(Length = 100, IsNullable = false)]
    public EncryPasswordValueObject EncryPassword { get; private set; } = new EncryPasswordValueObject();
    
    /// <summary>
    /// 邮箱是否已验证
    /// </summary>
    [SugarColumn(IsNullable = false)]
    public bool EmailConfirmed { get; set; }
    
    /// <summary>
    /// 用户角色，区分普通用户和管理员
    /// </summary>
    [SugarColumn(IsNullable = false)]
    public UserRole Role { get; set; } = UserRole.NormalUser;

    /// <summary>
    /// 头像URL
    /// </summary>
    [SugarColumn(Length = 256, IsNullable = true)]
    public string AvatarUrl { get; private set; }

    /// <summary>
    /// 用户状态
    /// </summary>
    [SugarColumn(IsNullable = false)]
    public UserStatus Status { get; private set; } = UserStatus.Offline;

    /// <summary>
    /// 安全戳，用于验证令牌和会话
    /// </summary>
    [SugarColumn(IsNullable = true)]
    public string SecurityStamp { get; set; }

    /// <summary>
    /// 创建时间
    /// </summary>
    [SugarColumn(IsNullable = false)]
    public DateTime CreationTime { get; set; }
    
    /// <summary>
    /// 最后登录时间
    /// </summary>
    [SugarColumn(IsNullable = true)]
    public DateTime? LastLoginTime { get; set; }

    /// <summary>
    /// 是否已删除
    /// </summary>
    [SugarColumn(IsNullable = false)]
    public bool IsDeleted { get; set; }

    /// <summary>
    /// 构造函数 - 供ORM使用
    /// </summary>
    public UserAggregateRoot()
    {
    }

    /// <summary>
    /// 创建新用户
    /// </summary>
    public UserAggregateRoot(
        string userName,
        string nickName,
        string email,
        string phoneNumber,
        string password)
    {
        UserName = userName;
        NickName = nickName;
        Email = email;
        PhoneNumber = phoneNumber;
        EncryPassword = new EncryPasswordValueObject(password);
        Status = UserStatus.Offline;
        CreationTime = DateTime.Now;
        IsDeleted = false;
    }

    /// <summary>
    /// 更新用户资料
    /// </summary>
    public void UpdateProfile(string nickName, string avatarUrl)
    {
        NickName = nickName;
        AvatarUrl = avatarUrl;
    }

    /// <summary>
    /// 更新登录信息
    /// </summary>
    public void UpdateLoginInfo(DateTime loginTime)
    {
        LastLoginTime = loginTime;
    }

    /// <summary>
    /// 构建密码，MD5盐值加密
    /// </summary>
    public UserAggregateRoot BuildPassword(string? password = null)
    {
        //如果不传值，那就把自己的password当作传进来的password
        if (password == null)
        {
            if (EncryPassword?.Password == null)
            {
                //TODO 后台确保密码不空
                throw new ArgumentNullException(nameof(EncryPassword.Password));
            }
            password = EncryPassword.Password;
        }
        EncryPassword.Salt = MD5Helper.GenerateSalt();
        EncryPassword.Password = MD5Helper.SHA2Encode(password, EncryPassword.Salt);
        return this;
    }

    /// <summary>
    /// 判断密码和加密后的密码是否相同
    /// </summary>
    /// <param name="password"></param>
    /// <returns></returns>
    public bool JudgePassword(string password)
    {
        if (EncryPassword.Salt is null)
        {
            throw new ArgumentNullException(EncryPassword.Salt);
        }
        var p = MD5Helper.SHA2Encode(password, EncryPassword.Salt);
        if (EncryPassword.Password == MD5Helper.SHA2Encode(password, EncryPassword.Salt))
        {
            return true;
        }
        return false;
    }
}